package it.gtd.swimpool.controller.resources;

import it.gtd.swimpool.model.business.LookupManager;
import it.gtd.swimpool.model.entity.*;

import javax.ejb.EJB;
import javax.ejb.Stateless;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import javax.ws.rs.*;
import javax.ws.rs.core.MediaType;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;

@Stateless
@Path("/")
public class LookupResource extends SecuredResource {
    @PersistenceContext
    private EntityManager entityManager;

    @EJB
    private LookupManager lookupManager;

    private static boolean firstSearch = true;

    @GET
    @Path("/users")
    @Produces(MediaType.APPLICATION_JSON)
    public Collection<User> getUsers(
            @QueryParam("name") String name,
            @DefaultValue("0") @QueryParam("start") int start,
            @DefaultValue("20") @QueryParam("count") int count
    ) {
        Collection<User> res = lookupManager.lookupUsers(count, start, name);
        if (firstSearch && !"OFF".equals(System.getenv("TEST"))) {
            firstSearch = false;

            SuperUser superUser = new SuperUser("su@default.du");
            superUser.setPassword("password");
            superUser.setName("Super user");
            superUser.setDescription("Amazing description");
            superUser.setInformation("Once upon a time...");
            superUser.activate();
            entityManager.persist(superUser);

            Administrator administrator = new Administrator("administrator@default.du");
            administrator.setPassword("password");
            administrator.activate();
            entityManager.persist(administrator);

            User user = new User("user@default.du");
            user.setPassword("password");
            user.activate();
            entityManager.persist(user);

            user.addFriend(administrator);

            Skill skill = new Skill();
            skill.setName("Lurking");
            skill.setApprover(administrator);
            entityManager.persist(skill);

            administrator.addSkill(skill);
            superUser.addSkill(skill);

            Feedback feedback = new Feedback(administrator, superUser, skill);
            feedback.setRating(Rating.FiveStar);
            entityManager.persist(feedback);

            return lookupManager.lookupUsers(count, start, name);
        } else {
            return res;
        }
    }

    @GET
    @Path("/help")
    @Produces(MediaType.APPLICATION_JSON)
    public Collection<User> getHelp(
            @CookieParam(Cookie.SESSION_ID) String sessionId,
            @QueryParam("skills")    List<Integer> skillIds,
            @QueryParam("minRating")   @DefaultValue("0")  int minRating,
            @QueryParam("onlyFriends") @DefaultValue("0")  int onlyFriends,
            @QueryParam("start")       @DefaultValue("0")  int start,
            @QueryParam("size")        @DefaultValue("20") int size
    ) {
        Collection<User> friends = null;
        boolean onlyFriendsBool = (onlyFriends != 0);

        if (null != sessionId && onlyFriendsBool) {
            User caller =  checkUser(sessionId);
            friends = caller.getFriends();
        }

        List<Skill> skills = new ArrayList<Skill>();
        for (Integer skillId : skillIds) {
            Skill skill = entityManager.find(Skill.class, skillId);
            if (null != skill) {
                skills.add(skill);
            }
        }

        Rating rating = null;

        switch (minRating) {
            case 1: rating = Rating.OneStar;
                    break;
            case 2: rating = Rating.TwoStar;
                    break;
            case 3: rating = Rating.ThreeStar;
                    break;
            case 4: rating = Rating.FourStar;
                    break;
            case 5: rating = Rating.FiveStar;
        }

        return lookupManager.searchForHelp(skills, friends, rating, size, start);
    }

    @GET
    @Path("/list")
    @Produces(MediaType.APPLICATION_JSON)
    public List<Integer> list(@QueryParam("item") List<Integer> items) {
        return items;
    }
}
